Airbnb JavaScript Style Guide: https://github.com/airbnb/javascript
2022.2.22 星期二 :
1 类型
2 引用
3 对象
3.7 不要直接调用 Object.prototype上的方法,如 hasOwnProperty、propertyIsEnumerable、isPrototypeOf。
3.8 对象浅拷贝时,更推荐使用扩展运算符(即 … 运算符),而不是 Object.assign。获取对象指定的几个属性时,用对象的 rest 解构运算符(即 … 运算符)更好。eslint: prefer-object-spread
4 数组
4.3 用扩展运算符做数组浅拷贝,类似上面的对象浅拷贝。
4.4 用 … 运算符而不是 Array.from 来将一个可迭代的对象转换成数组。
4.5 用 Array.from 将一个类数组对象转成一个数组。
4.6 用 Array.from 而不是 … 运算符去做 map 遍历。 因为这样可以避免创建一个临时数组。1
2
3
4
5// ### 4.6
// bad
const baz = [...foo].map(bar);
// good
const baz = Array.from(foo, bar);
5 解构
6 字符串
7 函数
7.1 使用命名函数表达式而不是函数声明。eslint: func-style
7.6 不要使用 arguments,用收集参数语法 … 代替。eslint: prefer-rest-params
7.9 把默认参数赋值放在最后。eslint: default-param-last
7.11 函数定义部分要有空格。eslint: space-before-function-paren space-before-blocks
7.12 不要修改参数. eslint: no-param-reassign
为什么?操作参数对象对原始调用者会导致意想不到的副作用。就是不要改参数的数据结构,保留参数原始值和数据结构。
7.13 不要对参数重新赋值。eslint: no-param-reassign
1 | // ### 7.6 |
8 箭头函数
8.2 如果函数体由一个没有副作用的 表达式 语句组成,删除大括号和 return。否则,使用大括号和 return 语句。 eslint: arrow-parens, arrow-body-style
8.3 如果表达式涉及多行,把他包裹在圆括号里以提高可读性。
8.4 在箭头函数参数两头,总是使用小括号包裹住参数,这样做使代码更清晰且一致. eslint: arrow-parens
8.5 避免箭头函数(=>)和比较操作符(<=, >=)混淆. eslint: no-confusing-arrow
8.6 使箭头函数体有一个清晰的返回。 eslint: implicit-arrow-linebreak
9 类与构造函数
10 模块
10.2 不要用 import 通配符, 即 * 这种方式。
10.3 不要直接从 import 中直接 export。
10.4 一个路径只 import 一次。eslint: no-duplicate-imports
10.5 不要导出可变的东西。eslint: import/no-mutable-exports
10.6 在一个单一导出模块里,用 export default 更好。eslint: import/prefer-default-export
10.8 多行 import 应该缩进,就像多行数组和对象字面量一样。
11 迭代器与生成器
11.1 不要用迭代器。使用 JavaScript 高级函数代替 for-in、 for-of。eslint: no-iterator no-restricted-syntax
<!– 13.5 不要使用链式声明变量。 eslint: no-multi-assign
为什么?链式声明变量会创建隐式全局变量。
–>
13.6 不要使用一元自增自减运算符(++, –). eslint no-plusplus
13.7 在赋值的时候避免在 = 前/后换行。 如果你的赋值语句超出 max-len,那就用小括号把这个值包起来再换行。eslint operator-linebreak.
17.2 不要用选择操作符代替控制语句。
PS: 和常规的劝法相反啊。
1
2
3
4
5
6
7 // bad
!isRunning && startRunning();
// good
if (!isRunning) {
startRunning();
}18 注释
18.2 单行注释用 //,将单行注释放在被注释区域上面。如果注释不是在第一行,那么注释前面就空一行。
19 空格
19.6 当出现长的方法链式调用时(>2个)用缩进。用点开头强调该行是一个方法调用,而不是一个新的语句。eslint: newline-per-chained-call no-whitespace-before-property
19.7 在一个代码块后下一条语句前空一行。
PS: 看起来是清晰。但是有点占行啊。– 代码人永无畏惧:行数多了还不好吗。19.8 不要用空白行填充块。eslint: padded-blocks
19.9 不要在代码之间使用多个空白行填充。eslint: no-multiple-empty-lines
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 // good
// ### 19.6
const leds = stage.selectAll('.led')
.data(data)
.enter().append('svg:svg')
.classed('led', true)
.attr('width', (radius + margin) * 2)
.append('svg:g')
.attr('transform', `translate(${radius + margin},${radius + margin})`)
.call(tron.led);
// ### 19.13
const foo = jsonData
&& jsonData.foo
&& jsonData.foo.bar
&& jsonData.foo.bar.baz
&& jsonData.foo.bar.baz.quux
&& jsonData.foo.bar.baz.quux.xyzzy;PS: 咱就是说空格/行也安排的明明白白。
20 逗号
20.1 不要前置逗号。eslint: comma-style
20.2 额外结尾逗号: 要 eslint: comma-dangle
注意,逗号不应出现在使用了 … 操作符后的参数后面
1
2
3
4
5
6
7 // good (注意,逗号不应出现在使用了 ... 操作符后的参数后面)
createHero(
firstName,
lastName,
inventorOf,
...heroArgs
)21 分号
21.1 要分号! eslint: semi
PS: 现在的做法是在必须加分号的地方前置分号。比如:(), []
。
最好加一加。22 类型转换与强制转换
TODO:
23 命名规范
23.2 用小驼峰命名法来命名你的对象、函数、实例。eslint: camelcase
PS: 有时会用下划线。前半部分是小驼峰,后半部分表示所属关系或者状态。借鉴css BEM。
命名长,无奈之举。不推荐。23.4 不要用前置或后置下划线。eslint: no-underscore-dangle
为什么?JavaScript 没有私有属性或私有方法的概念。尽管前置下划线通常的概念上意味着私有,事实上,这些属性是完全公有的,因此这部分也是你的 API 的内容。这一概念可能会导致开发者误以为更改这个不会导致崩溃或者不需要测试。如果你想要什么东西变成私有,那就不要让它在这里出现。
PS: 有时会把一些mock,测试数据,上线不需要的数据 前置下划线处理。23.5 不要保存引用 this,用箭头函数或 函数绑定——Function#bind。
PS: 看情况吧。有时候需要保存引用呢。除非都用箭头函数。23.6 export default 导出模块A,则这个文件名也叫 A.*, import 时候的参数也叫 A。 大小写完全一致。
23.9 简称和缩写应该全部大写或全部小写。
23.10 你可以用全大写字母设置静态变量,他需要满足三个条件。
PS: 有些全局的配置或定义,会用。并不会把所有的const 都定义成大写:大写不好读。
1
2
3
4
5
6
7
8
9
10
11
12
13 // ### 23.9
// good
import SMSContainer from './containers/SMSContainer';
const HTTPRequests = [
// ...
];
const httpRequests = [
// ...
];
import TextMessageContainer from './containers/TextMessageContainer';24 Get-Set 访问器
24.1 不需要使用属性的访问器函数。
24.2 不要使用 JavaScript 的 getters/setters,因为他们会产生副作用,并且难以测试、维护和理解。相反的,你可以用 getVal() 和 setVal(‘hello’) 去创造你自己的访问器函数。
24.4 用 get() 和 set() 函数是可以的,但是要一起用。25 事件
回调入参用对象方便处理。
26 jQuery
常规的那些处理。
27 ECMAScript 5 兼容性
28 ECMAScript 6+ (ES 2015+) 风格
ECMAScript 6+ (ES 2015+) 风格
28.1 这是收集到的各种ES6特性的链接
箭头函数——Arrow Functions
类——Classes
对象缩写——Object Shorthand
对象简写——Object Concise
对象计算属性——Object Computed Properties
模板字符串——Template Strings
解构赋值——Destructuring
默认参数——Default Parameters
剩余参数——Rest
数组拓展——Array Spreads
Let and Const
幂操作符——Exponentiation Operator
迭代器和生成器——Iterators and Generators
模块——Modules
28.2 不要用 TC39 proposals, TC39 还没有到 stage 3。为什么? 它还不是最终版, 他可能还有很多变化,或者被撤销。我们想要用的是 JavaScript, 提议还不是 JavaScript。
29 标准库
标准库中包含一些功能受损但是由于历史原因遗留的工具类
29.1 用 Number.isNaN 代替全局的 isNaN。 eslint: no-restricted-globals
为什么?全局 isNaN 强制把非数字转成数字, 然后对于任何强转后为 NaN 的变量都返回 true 如果你想用这个功能,就显式的用它。
29.2 用 Number.isFinite 代替 isFinite. eslint: no-restricted-globals30 测试
30.1 Yup.
30.2 No, but seriously:
无论用哪个测试框架,你都需要写测试。
尽量去写很多小而美的纯函数,减少突变的发生
小心 stub 和 mock —— 这会让你的测试变得脆弱。
在 Airbnb 首选 mocha。 tape 偶尔被用来测试一些小的、独立的模块。
100% 测试覆盖率是我们努力的目标,即便实际上很少达到。
每当你修了一个 bug, 都要写一个回归测试。 一个 bug 修复了,没有回归测试,很可能以后会再次出问题。31 性能
On Layout & Web Performance
String vs Array Concat
Try/Catch Cost In a Loop
Bang Function
jQuery Find vs Context, Selector
innerHTML vs textContent for script text
Long String Concatenation
Are Javascript functions like map(), reduce(), and filter() optimized for traversing arrays?32 资源
33 In the Wild
34 Translation
35 The JavaScript Style Guide Guide
36 Chat With Us About JavaScript
37 Contributors
38 License
39 Amendments
1 类型
2 引用
3 对象
4 数组
5 解构
6 字符串
7 函数
8 箭头函数
9 类与构造函数
10 模块
11 迭代器与生成器
12 属性
13 变量
14 提升
15 比较运算符与相等
16 块
17 控制语句
18 注释
19 空格
20 逗号
21 分号
22 类型转换与强制转换
23 命名规范
24 Get-Set 访问器
25 事件
26 jQuery
27 ECMAScript 5 兼容性
28 ECMAScript 6+ (ES 2015+) 风格
29 标准库
30 测试
31 性能
32 资源
33 In the Wild
34 Translation
35 The JavaScript Style Guide Guide
36 Chat With Us About JavaScript
37 Contributors
38 License
39 Amendments